package com.etonenet.base.test;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import com.etonenet.base.service.UserInfoService;

@Component
public class LockUserListener {

	private static Logger logger = LoggerFactory.getLogger(LockUserListener.class);

	public LockUserListener() {

	}

	@Autowired
	private ServletContext servletContext;
	@Autowired
	private UserInfoService userInfoService;

	/**
	 * 监听登陆失败事件
	 * 
	 * @param event
	 */
	@EventListener
	public void onAuthenticationFailureBadCredentialsEvent(AuthenticationFailureBadCredentialsEvent event) {
		logger.debug("{}", event);
		AuthenticationFailureBadCredentialsEvent authEvent = (AuthenticationFailureBadCredentialsEvent) event;
		Authentication authentication = (Authentication) authEvent.getSource();
		String username = (String) authentication.getPrincipal();
		addCount(username);
	}

	/**
	 * 监听登陆成功事件
	 * 
	 * @param event
	 */
	@EventListener
	public void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
		AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;
		Authentication authentication = (Authentication) authEvent.getSource();
		UserInfo userInfo = (UserInfo) authentication.getPrincipal();
		String username = userInfo.getUsername();
		cleanCount(username);
	}

	protected void addCount(String username) {
		Map<String, Integer> lockUserMap = getLockUserMap();
		Integer count = lockUserMap.get(username);

		if (count == null) {
			lockUserMap.put(username, Integer.valueOf(1));
		} else {
			int resultCount = count.intValue() + 1;

			if (resultCount > 3) {
				UserInfo userInfo = (UserInfo) userInfoService.loadUserByUsername(username);
				if (userInfo != null) {
					userInfo.lockAccount();
					logger.debug("lock account:{}", username);
				} else {
					logger.debug("not lock account:{}", username);
				}
			} else {
				lockUserMap.put(username, Integer.valueOf(resultCount));
				logger.debug("not lock account:{}", username);
			}
		}
	}

	protected void cleanCount(String username) {
		Map<String, Integer> lockUserMap = getLockUserMap();

		if (lockUserMap.containsKey(username)) {
			lockUserMap.remove(username);
		}
	}

	@SuppressWarnings("unchecked")
	protected Map<String, Integer> getLockUserMap() {
		Map<String, Integer> lockUserMap = (Map<String, Integer>) servletContext.getAttribute("LOCK_USER_MAP");

		if (lockUserMap == null) {
			lockUserMap = new HashMap<String, Integer>();
			servletContext.setAttribute("LOCK_USER_MAP", lockUserMap);
		}

		return lockUserMap;
	}
}
